#pragma once
# include "EncoderFilter.h"
# include <atomic>
# include <mutex>
# include <queue>
# include <thread>
# include <condition_variable>

struct AVFormatContext;
struct AVStream;
struct AVRational;

class _declspec(dllexport) SaveFileFilter : public EncoderFilter {
public:
	SaveFileFilter();
	bool initFileFilter(const char* _file_name, uint8_t* _video_encoder_codec_ctx, uint8_t* _audio_encoder_codec_ctx);
	void saveFile();
	virtual void afterVideoEncode(AVPacket* _packet) override;
	virtual void afterAudioEncode(AVPacket* _packet) override;
	~SaveFileFilter();
private:
	AVFormatContext* m_save_ctx = nullptr;
	AVStream* m_save_audio_stream = nullptr;
	AVStream* m_save_video_stream = nullptr;
	AVRational* m_video_time_base = nullptr;
	std::atomic_bool m_ready = false;
	std::atomic_int64_t m_video_pts = 0;
	std::atomic_int64_t m_audio_pts = 0;
	std::mutex m_mutex;
	std::condition_variable m_cv;
	std::queue<AVPacket*> m_queue;
	std::thread* m_thread = nullptr;

	void writeFrame();
	void push(AVPacket* _packet);
};
